iT邦幫忙

2023 iThome 鐵人賽

DAY 19
0
Software Development

I Use Linux BTW: 談Linux與其指令系列 第 19

Day19: 實作篇:使用shell script問chatGPT問題

  • 分享至 

  • xImage
  •  

在shell問chatGPT問題

今天來做個實作,使用shell script串連OPENAI API問chatGPT問題

事前準備

  1. 一個還有額度的OPENAI API KEY
    <insert tutorial about how to get an OPENAI API KEY>

步驟

  1. 初始化(清空歷史記錄)
  2. 接收用戶輸入作為問題
  3. 將用戶的問題存入JSON後對OPENAI的API傳送request
  4. 接收response後輸出結果並存入JSON

實作

  1. 初始化(清空歷史記錄)
    一開始因為我們不想要把之前的紀錄也當成歷史紀錄,所以需要用一個預設JSON來蓋過
echo '{"history":[]}' >data.json

如果你沒有指定API KEY請先使用export OPENAI_API_KEY=<your-api-key>,如果不想每次都指定可以把這行指令加入.bashrc

清空歷史紀錄後,為了確保功能正常,需要先檢查OPENAI_API_KEY這個變數是否被指定,為了避免這個問題,我在shell script中設定了一個檢查的條件式。
我們可以使用以下指令來將api key加入系統環境

$ echo 'export OPENAI_API_KEY=<your-api-key>' >> .bashrc
  1. 接收用戶輸入作為問題
    初始化完後接下來開始接收用戶輸入,這邊使用read讀取使用者輸入並存至變數content
read content

接下來需要檢查輸入,這邊有四種情況可能出現
1. 輸入字串為空
2. 要求退出
3. 要求手動清空歷史紀錄
4. 正常情況
因此需要在接收到訊息後針對以上三種狀況進行特殊處理

if [[ -z $content]]
then
    >&2 echo "GTFO"
    exit 1
fi
if [[ $content == 'q' ]]
then
    echo "bye"
    exit
elif [[ $content == 'clear']]
then
    echo '{"history":[]}' >data.json
fi
  1. 將用戶的問題存入JSON後對OPENAI的API傳送request
    接下來就可以開始準備資料了,openai chat completion接收一個存取JSON的LIST作為歷史紀錄,所以我們需要將用戶輸入轉為JSON後存入history
data=$(jq ".history[.history | length ] |= . + {\"role\": \"user\", \"content\":\"${content//\"/\\\"}\"}" data.json)
(echo $data | jq -r .) >data.json

儲存後將這個list處理為字串後作為payload使用curl傳送請求

curl_data="{
        \"model\": \"gpt-3.5-turbo\",
        \"messages\": "$(echo $data | jq '.history')",
        \"max_tokens\": 150
    }"
response=$(
        curl https://api.openai.com/v1/chat/completions \
            -H "Content-Type: application/json" \
            -H "Authorization: Bearer $OPENAI_API_KEY" \
            -d "$(echo $curl_data | jq -r .)"
    )
  1. 接收response後輸出結果並存入JSON
echo $response | jq -r '.choices[0].message.content'
response_msg=$(echo $response | jq -r '.choices[0].message')
new_data=$(jq ".history[.history | length ] |= . + $response_msg" data.json)
(echo $new_data | jq -r .) >data.json

以下是完整的code

#!/bin/bash
function ask() {
    data=$(jq ".history[.history | length ] |= . + {\"role\": \"user\", \"content\":\"${content//\"/\\\"}\"}" data.json)

    (echo $data | jq -r .) >data.json
    curl_data="{
        \"model\": \"gpt-3.5-turbo\",
        \"messages\": "$(echo $data | jq '.history')",
        \"max_tokens\": 150
    }"
    response=$(
        curl https://api.openai.com/v1/chat/completions \
            -H "Content-Type: application/json" \
            -H "Authorization: Bearer $OPENAI_API_KEY" \
            -d "$(echo $curl_data | jq -r .)"
    )
    echo $response | jq -r '.choices[0].message.content'
    response_msg=$(echo $response | jq -r '.choices[0].message')
    new_data=$(jq ".history[.history | length ] |= . + $response_msg" data.json)
    (echo $new_data | jq -r .) >data.json
}

function clear_history() {
    echo '{"history":[]}' >data.json
}
# 檢查OPENAI_API_KEY這個變數是否存在
if [[ -z $OPENAI_API_KEY ]]; then
    >&2 echo 'key is not provided'
    exit 1
fi
# 預設清空歷史紀錄
clear_history
echo 'Welcome to OpenAI chatbot'



# 持續運行直到輸入為空字串或q(表示退出)
while true
do
    echo 'what do you want to ask to me? (type "q" to exit)'
    read content

    if [[ -z $content ]]; then
        >&2 echo 'GTFO'
        exit 1
    fi
    if [[ $content = 'q' ]]; then
        echo 'bye'
        exit 0
    elif [[ $content = 'clear' ]]; then
        clear_history
        echo 'history cleared'
        continue
    fi
    ask
    if [[ -z $(cat data.json) ]]; then
        echo '{"history":[]}' >data.json
    fi
done

上一篇
Day18: shell script中的條件式
下一篇
Day20: 新增/刪除使用者
系列文
I Use Linux BTW: 談Linux與其指令30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言